package de.tudresden.inf.ggp.basicplayer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.palamedes.gdl.core.model.*;

public class CListAction implements Serializable {

	private List<CAction> ListAction;
	
	public CListAction(){
		ListAction=new LinkedList<CAction>();
		ListAction.clear();
	}
	
	public CListAction(IMove[] ActArray){
		ListAction=new LinkedList<CAction>();
		ListAction.clear();
		for(int i=0;i<ActArray.length;i++){
			ListAction.add(new CAction(ActArray[i]));
		}
	}
	
	public List getListAction() {
		return ListAction;
	}

	public void setListAction(List listAction) {
		ListAction = listAction;
	}
	
	public void Clear(){
		this.ListAction.clear();
	}
	
	public boolean IsExist(IMove Act){
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			CAction cac=it.next();
			if(cac.getActionID().equals(Act)){
				return true;
			}
		}
		return false;
	}
	
	public int getNVisitAction(IMove Act){
		int result=-1;
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			CAction cac=it.next();
			if(cac.getActionID().equals(Act)){
				result=cac.getNVisit();
			}
		}
		return result;
	}
	
	public int getTotalValueAction(IMove Act){
		int result=-1;
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			CAction cac=it.next();
			if(cac.getActionID().equals(Act)){
				result=cac.getTotalValue();
			}
		}
		return result;
	}
	
	public int getAvgValueAction(IMove Act){
		int result=-1;
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			CAction cac=it.next();
			if(cac.getActionID().equals(Act)){
				result=cac.getAvgValue();
			}
		}
		return result;
	}  
	
	public int getNVisitList(){
		int result=0;
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			result=+it.next().getNVisit();
		}
		return result;
	}
	
	public int getTotalValueList(){
		int result=0;
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			result=+it.next().getTotalValue();
		}
		return result;
	} 
	
	public int getAvgValueList(){
		return this.getTotalValueList()/this.getNVisitList();
	}

	public int getActionCount(){
		return this.ListAction.size();
	}
	
	public boolean addNewAction(IMove Act){
		return this.ListAction.add(new CAction(Act));
	}  
	
	public boolean addNewActions(IMove[] ActArray){
		boolean result=false;
		for(int i=0;i<ActArray.length;i++){
			ListAction.add(new CAction(ActArray[i]));
			result=true;
		}
		return result;
	}  
	
	public boolean addActionVisit(IMove Act, int N){
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			CAction cac=it.next();
			if(cac.getActionID().equals(Act)){
				cac.addVisit(N);
				return true;
			}
		}
		return false;
	}  

	public boolean addActionValue(IMove Act, int Value){
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			CAction cac=it.next();
			if(cac.getActionID().equals(Act)){
				cac.addValue(Value);
				return true;
			}
		}
		return false;
	}  
	
	public IMove getBestAvgAction(){
		IMove imove=null;
		CAction cac=null;
		int result=0;
		Iterator<CAction> it=this.ListAction.iterator();
		while(it.hasNext()){
			cac= it.next();
			if(cac.getAvgValue()>result){
				result=cac.getAvgValue();
				imove=cac.getActionID();
			}
		}
		return imove;
	}
		
	public  boolean saveToFile(String FileName){
		File file=new File("source//de//tudresden//inf//ggp//basicplayer//"+FileName);
		try{
			ObjectOutputStream objOutputStream=new ObjectOutputStream(new FileOutputStream(file));
			objOutputStream.writeObject(ListAction);
			objOutputStream.close();
		}catch(IOException e){
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	public List loadFromFile(String FileName) throws Exception{
		File file=new File("source//de//tudresden//inf//ggp//basicplayer//"+FileName);
		if(!file.exists()){
			throw new FileNotFoundException();
		}
		List<CAction> ListActionTemp=null;
		try{
			ObjectInputStream objInputStream=new ObjectInputStream(new FileInputStream(file));
			ListActionTemp=(List<CAction>) objInputStream.readObject();
			objInputStream.close();
		}catch(IOException e){
			e.printStackTrace();
		}
		return ListActionTemp;
	}
}
/*
 * Field 
 * ListAction: contains a list of CAction 
 
•  Constructor 
o  Public CListAction(): create new and clear ListAction 
o  Public CListAction(ActArray: IMove[]): create new ListAction with ActArray as the initial 
actions on the ListAction. NVisit=0, TotalValue=0. 
 
•  Method 
o  Public void Clear():  
  clear ListAction 
o  Public boolean IsExist(Act: IMove):  
  search Act on the ListAction. Match Act with ActionID.  
  Return true if Act is found, return false is Act is not found. 
o  Public integer getNVisitAction(Act:IMove):  
  return NVisit of the Act. Search Act on the ListAction,  
  if found, return CAction.getNVisit from Act. If not found, return -1. 
o  Public integer getTotalValueAction(Act:IMove):  
  return TotalValue of the Act. Search Act on the ListAction,  
  If found, return CAction.getTotalValue from Act. If not found, return -1. 
o  Public integer getAvgValueAction(Act:IMove):  
  return average value of the Act. Search Act on the ListAction,  
  If found, return CAction.getAvgValue from Act. If not found, return -1. 
o  Public integer getNVisitList: return sum of NVisit from all actions in ListAction 
o  Public integer getTotalValueList: return sum of TotalValue from all actions in ListAction 
o  Public integer getAvgValueList: return the average value of all actions, that is 
getTotalValueList/getNVisitList   2
o  Public integer getActionCount: return the number of the action (count) in ListAction. 
o  Public boolean addNewAction(Act: IMove):  
  add Act to the ListAction, with NVisit=0 and TotalValue=0. 
o  Public boolean addNewActions(ActArray: IMove[]):  
  add ActArray (array of IMove) to the ListAction with NVisit=0 and TotalValue=0. 
o  Public boolean addActionVisit(Act:IMove, N:integer):  
  add N to the NVisit of Act.  
  Search Act on the ListAction, use CAction.addVisit(N) to add N to the NVisit of the 
Act.  
  Return true if addVisit is done. Return false if addVisit is failed (e.g. Act is not on 
the ListAction). 
o  Public boolean addActionValue(Act:IMove, Value:integer):  
  add Value to the TotalValue of Act.  
  Search Act on the ListAction, use CAction.addValue(Value) to add the Value to 
TotalValue of the Act. 
  Return true if addValue is done. Return false if addValue is failed (e.g. Act is not 
on the ListAction). 
 */
 